# from ppadb.client import Client as AdbClient
# from ppadb.device import Device as AdbDevice
from PySide6.QtCore import QObject, QTimer, Slot, Signal, Property, QEnum, Qt
from PySide6.QtQml import QmlElement, QmlSingleton
import logging
# from .constants import *
import subprocess
import threading

class FlashToolWorker(QObject):
    adb_device_connect_state_changed = Signal()
    fastboot_device_connect_state_changed = Signal()
    
    flashOutput = Signal(str)
    error = Signal(str)
    
    flashFirmwareFinished = Signal(bool, str)
    rebootDeviceFinished = Signal(bool, str)
    rebootToFastbootModeFinished = Signal(bool, str)
    
    def __init__(self, parent=None):
        super().__init__(parent)
        self._adb_devices = []
        self._fastboot_devices = []
        self._adb_device_connected = False
        self._fastboot_device_connected = False
        
        self.timer_adb = QTimer(self)
        self.timer_adb.timeout.connect(self._checkAdbDevice)
        self.timer_adb.start(500)
        self.timer_fastboot = QTimer(self)
        self.timer_fastboot.timeout.connect(self._checkFastbootDevice)
        self.timer_fastboot.start(500)
    
    def adbDeviceConnected(self):
        return self._adb_device_connected

    def fastbootDeviceConnected(self):
        return self._fastboot_device_connected
    
    def adbDevices(self):
        return self._adb_devices

    def fastbootDevices(self):
        return self._fastboot_devices
    
    @Slot()
    def _checkAdbDevice(self):
        result = subprocess.run(["adb", "devices"], shell=True, capture_output=True, text=True, timeout=5)
        # logging.debug(f"adb devices output: {result.stdout}")
        self._adb_devices = []
        if result.returncode == 0:
            lines = result.stdout.strip().split("\n")
            for line in lines[1:]:
                if "device" in line:
                    self._adb_devices.append(line.split("\t")[0])
                    if not self._adb_device_connected:
                        self._adb_device_connected = True
                        logging.debug(f"ADB device connected: {line}")
                        self.adb_device_connect_state_changed.emit()
                    return
        
            if self._adb_device_connected:
                self._adb_device_connected = False
                logging.debug(f"ADB device disconnected")
                self.adb_device_connect_state_changed.emit()
        else:
            logging.error(f"adb devices command failed with return code {result.returncode} and output {result.stderr}")
            self.error.emit(f"adb devices command failed with return code {result.returncode} and output {result.stderr}")
    
    @Slot()
    def _checkFastbootDevice(self):
        result = subprocess.run(["fastboot", "devices"], shell=True, capture_output=True, text=True, timeout=5)
        # logging.debug(f"fastboot devices output: {result.stdout}")
        self._fastboot_devices = []
        if result.returncode == 0:
            lines = result.stdout.strip().split("\n")
            for line in lines:
                if line.strip():
                    self._fastboot_devices.append(line.split("\t")[0])
                    if not self._fastboot_device_connected:
                        self._fastboot_device_connected = True
                        logging.debug(f"Fastboot device connected: {line}")
                        self.fastboot_device_connect_state_changed.emit()
                    return
        
            if self._fastboot_device_connected:
                self._fastboot_device_connected = False
                logging.debug(f"Fastboot device disconnected")
                self.fastboot_device_connect_state_changed.emit()
        else:
            logging.error(f"fastboot devices command failed with return code {result.returncode} and output {result.stderr}")
            self.error.emit(f"fastboot devices command failed with return code {result.returncode} and output {result.stderr}")
    
    # Reboot device to fastboot mode
    @Slot()
    def rebootToFastbootMode(self):
        fastboot_command = ['adb', 'shell', 'reboot', 'fastboot']
        try:
            result = subprocess.run(fastboot_command, 
                                    shell=True, 
                                    capture_output=True, 
                                    text=True, 
                                    timeout=10)
            if result.returncode == 0:
                logging.info("Device rebooted to fastboot successfully")
                self.rebootToFastbootModeFinished.emit(True, "Device rebooted to fastboot successfully")
                return True
            else:
                logging.error(f"Device reboot to fastboot failed with return code {result.returncode} and output {result.stderr}")
                self.rebootToFastbootModeFinished.emit(False, f"Device reboot to fastboot failed with return code {result.returncode} and output {result.stderr}")
                return False
        except Exception as e:
            logging.error(f"Device reboot to fastboot failed with exception {e}")
            self.error.emit(f"Device reboot to fastboot failed with exception {e}")
            self.rebootToFastbootModeFinished.emit(False, f"Device reboot to fastboot failed with exception {e}")
            return False
            
    # Flash firmware using fastboot
    @Slot(str)
    def flashFirmware(self, firmware_path):
        logging.info(f"Flashing firmware from path: {firmware_path}")
        fastboot_command = ["fastboot", "flash", "0x0", firmware_path]
        try:
            process = subprocess.Popen(fastboot_command, 
                                            stdout=subprocess.PIPE, 
                                            stderr=subprocess.STDOUT,
                                            universal_newlines=True,   # 以文本模式读取
                                            bufsize=1,                 # 行缓冲
                                            encoding='utf-8'           # 指定编码
                    )
            for line in process.stdout:
                self.flashOutput.emit(line)
            
            # 等待进程结束
            return_code = process.wait()
            if return_code == 0:
                logging.info("Firmware flashed successfully")
                self.flashFirmwareFinished.emit(True, "Firmware flashed successfully")
                return True
            else:
                logging.error(f"Firmware flashing failed with return code {return_code}")
                self.flashFirmwareFinished.emit(False, f"Firmware flashing failed with return code {return_code}")
                return False
        except Exception as e:
            logging.error(f"Firmware flashing failed with exception {e}")
            self.error.emit(f"Firmware flashing failed with exception {e}")
            self.flashFirmwareFinished.emit(False, f"Firmware flashing failed with exception {e}")
            return False

    # Reboot device from fastboot mode
    @Slot()
    def rebootDevice(self):
        try:
            result = subprocess.run(["fastboot", "reboot"], 
                                    shell=True, 
                                    capture_output=True, 
                                    text=True, 
                                    timeout=10)
            if result.returncode == 0:
                logging.info("Device rebooted successfully")
                self.rebootDeviceFinished.emit(True, "Device rebooted successfully")
                return True
            else:
                logging.error(f"Device reboot failed with return code {result.returncode} and output {result.stderr}")
                self.rebootDeviceFinished.emit(False, f"Device reboot failed with return code {result.returncode} and output {result.stderr}")
                return False
        except Exception as e:
            logging.error(f"Device reboot failed with exception {e}")
            self.error.emit(f"Device reboot failed with exception {e}")
            self.rebootDeviceFinished.emit(False, f"Device reboot failed with exception {e}")
            return False